package spitzer.flair.views;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.part.*;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;



import spitzer.flair.FlashPlugin;
import spitzer.flair.preferences.FlairPreferenceConstants;


/**
 * This sample class demonstrates how to plug-in a new
 * workbench view.
 */

public class FlashLogView extends ViewPart {

	private int updateInterval;
	private String filePath;
	private String regexFilter;
	private File file;
	private long lastModified;
	private Text txtLog;
	private Display display;
	private Timer timer;
	
	private PreferenceListener listener;
	

	private class PreferenceListener implements IPropertyChangeListener {
		public void propertyChange(PropertyChangeEvent event) {
			IPreferenceStore ps = FlashPlugin.getDefault().getPreferenceStore();
			
			updateInterval = ps.getInt(FlairPreferenceConstants.P_LOG_UPDATE_INTERVAL);
			if (updateInterval < 500) {
				updateInterval = 500;
			}
			filePath = ps.getString(FlairPreferenceConstants.P_LOG_PATH);
			regexFilter = ps.getString(FlairPreferenceConstants.P_REGEX_FILTER);
			file = new File(filePath);
			String log = getContents();
			txtLog.setText(log);
			txtLog.setTopIndex(txtLog.getLineCount());
		}
	}
	
	private class FileWatcher extends TimerTask {
		public void run() {
			long modified = file.lastModified();
			if (modified != lastModified) {
				lastModified = modified; 
				updateLog();
			}
		}
		
		private void updateLog() {
			display.syncExec(
					new Runnable() {
						public void run() {
							String log = getContents();
							txtLog.setText(log);
							txtLog.setTopIndex(txtLog.getLineCount());
						}
					});
		}
		
	}

	/**
	 * The constructor.
	 */
	public FlashLogView() {
		file = null;
	}

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
		IPreferenceStore ps = FlashPlugin.getDefault().getPreferenceStore();
		listener = new PreferenceListener();
        ps.addPropertyChangeListener(listener);
		
		updateInterval = ps.getInt(FlairPreferenceConstants.P_LOG_UPDATE_INTERVAL);
		if (updateInterval < 500) {
			updateInterval = 500;
		}
		filePath = ps.getString(FlairPreferenceConstants.P_LOG_PATH);
		regexFilter = ps.getString(FlairPreferenceConstants.P_REGEX_FILTER);
		
		file = new File(filePath);
		
		// TODO: Explore possibility of using specialized or console *Viewer
		//       and content provider instead of display canvas
		
		display = parent.getDisplay();
		txtLog = new Text(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		txtLog.setSize(parent.getSize());
		txtLog.setEditable(false);
		timer = new Timer(false); // why false?
		timer.schedule(new FileWatcher(), 0L, updateInterval);
		
		contributeToLocalToolbar();
	}
	
	private void contributeToLocalToolbar() {
		Action actionPreferences = new Action() {
			public void run() {
				PreferencesUtil.createPreferenceDialogOn(null, "spitzer.flair.preferences.FlairPreferences", null, null).open();
			}
		};
		actionPreferences.setText("Preferences");
		actionPreferences.setToolTipText("Open preferences page");
		actionPreferences.setImageDescriptor(
				FlashPlugin.getImageDescriptor("icons/elcl16/properties.gif"));

		IToolBarManager manager = getViewSite().getActionBars().getToolBarManager();
		manager.add(actionPreferences);
	}

	public void dispose() {
		IPreferenceStore ps = FlashPlugin.getDefault().getPreferenceStore();
		ps.removePropertyChangeListener(listener);
	}

	private String getContents() {
		StringBuffer contents = new StringBuffer();
		BufferedReader input = null;
		try {
			input = new BufferedReader(new FileReader(file));
			for (String line = null; (line = input.readLine()) != null;) {
				boolean append = false;
				if (regexFilter.length() > 0) {
					Pattern pattern = Pattern.compile(regexFilter);
					Matcher match = pattern.matcher(line);
					append = match.find();
				} else {
					append = true;
				}
				if (append) {
					contents.append(line + System.getProperty("line.separator"));
				}
			}
		}
		catch (FileNotFoundException ex) {
			ex.printStackTrace();
		}
		catch (IOException ex) {
			ex.printStackTrace();
		}
		finally {
			try {
				if (input != null) {
					input.close();
				}
			}
			catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		
		return contents.toString();		
	}


	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		txtLog.setFocus();
	}
}